import { menu } from '../../../app/decorator';

const { ccclass, property } = cc._decorator;

enum touchType {
    SINGLECLICK = 1,
    DOUBLECLICK = 2,
    LONGTOUCH = 3
}

@ccclass
@menu(__filename, '类型触摸')
export default class TouchHold extends cc.Component {
    @property
    _target: cc.Node = null;
    @property(cc.Node)
    get target() { return this._target || this.node; }
    set target(value) {
        this._target = value;
    }

    @property({ type: cc.Enum(touchType) })
    type: touchType = touchType.LONGTOUCH;

    @property({ visible() { return this.type !== touchType.SINGLECLICK; } })
    time: number = 0.7;

    private _touching = false;
    private _touchTime = 0;

    // 用来初始化组件或节点的一些属性，当该组件被第一次添加到节点上或用户点击了它的 Reset 菜单时调用。这个回调只会在编辑器下调用。
    resetInEditor() {
        this.target = this.node;
    }

    onLoad() { }

    onEnable() {
        this.target.on('touchstart', this.onTouchStart, this);
        this.target.on('touchmove', this.onTouchMove, this);
        this.target.on('touchend', this.onTouchEnd, this);
        this.target.on('touchcancel', this.onTouchCancel, this);
    }

    onDisable() {
        this.target.off('touchstart', this.onTouchStart, this);
        this.target.off('touchmove', this.onTouchMove, this);
        this.target.off('touchend', this.onTouchEnd, this);
        this.target.off('touchcancel', this.onTouchCancel, this);
    }

    onTouchStart() {
        if (this.type === touchType.LONGTOUCH) {
            this.scheduleOnce(function () {
                this.node.emit('longTouch', true);
            }, this.time);

            this._touching = true;
        }
    }

    onTouchMove(event) {
        if (this.type === touchType.LONGTOUCH && this._touching) {
            if (!this.target.getBoundingBoxToWorld().contains(event.touch)) {
                this.onTouchCancel();
            }
        }
    }

    onTouchEnd() {
        if (this.type === touchType.DOUBLECLICK) {
            let t = Date.now();
            if (t - this._touchTime <= this.time) {
                this._touchTime = 0;
                this.node.emit('doubleClick');
            } else {
                this._touchTime = t;
            }
        } else if (this.type === touchType.SINGLECLICK) {
            this.node.emit('singleClick');
        } else {
            this.onTouchCancel();
        }
    }

    onTouchCancel() {
        if (this._touching) {
            this.unscheduleAllCallbacks();
            this.node.emit('longTouch', false);
            this._touching = false;
        }
    }
}
